package com.common.android.utils.db;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;

import com.product.android.utils.LogUtils;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;


/**
 * Wrapper of SQLiteDatabase
 * Some as Spring JdbcTemplate
 * 
 * @see org.springframework.jdbc.core.JdbcTemplate
 * @see com.ch_linghu.fanfoudroid.db.dao.RowMapper
 */
public class SqliteTemplate {
    private static final String TAG = "SqliteTemplate";
    private boolean DEBUG = false;
    private SQLiteDatabase mDb;
    /**
     * Construct
     * @param tableName table name
     */
    public SqliteTemplate(SQLiteDatabase db) {
    	mDb=db;
    }
    
    /**
     * Insert a Row
     * @param table
     * @param nullColumnHack
     * @param values
     * @return the row ID of the newly inserted row, or -1 if an error occurred 
     * @see SQLiteDatabase#insert(String table, String nullColumnHack, ContentValues values)
     */
    public long insert(Query query) throws SQLException
    {
        query.setDb(mDb);
        long id = query.insert();
        if(DEBUG){
        	LogUtils.v(TAG, ((id != -1) ? "[Success] " : "[Fail] ") + "Insert " + query.getContentValues().toString());
        }
        return id;
    }
    
    /**
     * Delete a row
     * 
     * @param query
     * @return succeed or fail
     */
    public boolean delete(Query query)
    {
        query.setDb(mDb);
        int rows = query.delete();
        if(DEBUG){
        	LogUtils.v(TAG, ((rows > 0) ? "[Success] " : "[Fail] ") + "Delete " + query.toString());
        }
        return ( rows > 0 );
    }
    
    /**
     * Query For Object
     * @param <T>
     * @param query builder
     * @param rowMapper
     * @return object 
     * @throws DAOException 
     */
    public <T> T queryForObject(Query query, RowMapper<T> rowMapper) {
        query.setDb(mDb);
        Cursor cursor = query.select();
        T object = null;
        if(cursor!= null){
        	try {
        		cursor.moveToFirst();
            	object = rowMapper.mapRow(cursor, cursor.getCount());
			} finally {
				 cursor.close();
			}
        }
	    return object;
    }
    
    public int queryForInt(Query query) {
    	int count=0;
        query.setDb(mDb);
        Cursor cursor = query.select();
        if(cursor!= null){
        	 try {
            	 if(cursor.moveToFirst()){
                	 count=cursor.getInt(0);
            	 }
    		}
            finally {
    			 cursor.close();
    		}
        }
        return count;
    }
    
    /**
     * Query For long
     * @param <T>
     * @param query builder
     * @return int 
     * @throws DAOException 
     */
    public long queryForLong(Query query) {
    	long count=0;
        query.setDb(mDb);
        Cursor cursor = query.select();
        if(cursor != null){
        	 try {
            	 if(cursor.moveToFirst()){
                	 count=cursor.getLong(0);
                  }
    		}finally {
    			 cursor.close();
    		}
        }
        return count;
    }
    
    /**
     * Query For long
     * @param <T>
     * @param query builder
     * @return int 
     * @throws DAOException 
     */
    public long[] queryForLongArray(Query query) {
    	long count[]=new long[2];
        query.setDb(mDb);
        Cursor cursor = query.select();
        if(cursor!= null){
        	 try {
           	  if(cursor.moveToFirst()){
                	 count[0]=cursor.getLong(0);
                	 count[1]=cursor.getLong(1);
                  }
	   		} finally {
	   			 cursor.close();
	   		}
        }
       
        return count;
    }
    
    public String queryForOneString(Query query) {
    	String s=null;
        query.setDb(mDb);
        Cursor cursor = query.select();
        if(cursor!= null){
        	try {
           	 	if(cursor.moveToFirst()){
               	 s=cursor.getString(0);
               }
	   		} finally {
	   			 cursor.close();
	   		}
        }
        
        return s;
    }
    
    public String[] queryForArrString(Query query) {
    	String count[]=new String[2];
        query.setDb(mDb);
        Cursor cursor = query.select();
        if(cursor!= null){
        	 try {
            	 if(cursor.moveToFirst()){
                	 count[0]=cursor.getString(0);
                	 count[1]=cursor.getString(1);
                  }
    		} finally {
    			 cursor.close();
    		}
        }
       
        return count;
    }
    
    /**
     * Query for string   a,b
     * @param <T>
     * @param query builder
     * @param rowMapper
     * @return list of object
     */
    public String queryForString(Query query) {
        StringBuffer bf=new StringBuffer();
        Cursor cursor = queryForCursor(query);
        if(cursor!= null){
        	 try {
            	 while (cursor.moveToNext()) {
                 	bf.append(cursor.getLong(0));
                 	if(!cursor.isLast()){
                 		bf.append(",");	
                 	}
                 }
    		} finally {
    			 cursor.close();
    		}
        }
       
        return bf.toString();
    }
   
    
    /**
     * Query for list
     * @param <T>
     * @param query builder
     * @param rowMapper
     * @return list of object
     */
    public <T> List<T> queryForList(Query query, RowMapper<T> rowMapper) {
        List<T> list = new ArrayList<T>();
        Cursor cursor = queryForCursor(query);
        if(cursor!= null){
        	 try {
             	while (cursor.moveToNext()) {
                     list.add(rowMapper.mapRow(cursor, 1));
                 }
     		} finally {
     			 cursor.close();
     		}
        }
       
        return list;
    }
    
    /**
     * Query for cursor 
     * @param query builder
     * @return a cursor
     */
    public Cursor queryForCursor(Query query) {
        query.setDb(mDb);
        return query.select();
    }
    
    public Cursor queryForCursor(Query query,String querySql) {
        query.setDb(mDb);
        return query.select(querySql);
    }
    
    /**
     * Upload a row
     * @param query
     * @return the number of rows affected, or -1 if an error occurred
     */
    public int upload(Query query) {
        query.setDb(mDb);
        return query.update();
    }
    
    public Cursor query(String sql){
    	Query query=new Query(mDb);
    	return query.query(sql);
    }

    public void execSql(String sql){
    	mDb.execSQL(sql);
    }
    
    public ArrayList<String> queryForArrStringEx(Query query) {
    	ArrayList<String> list = new ArrayList<String>();
        Cursor cursor = queryForCursor(query);
        while (cursor.moveToNext()) {
            list.add(cursor.getString(0));
        }
        cursor.close();
        return list;
    }
    
    /**
     * Query for Vector
     * @param <T>
     * @param query builder
     * @param rowMapper
     * @return list of object
     */
    public <T> Vector<T> queryForVector(Query query, RowMapper<T> rowMapper) {
    	Vector<T> vector = new Vector<T>();
        Cursor cursor = queryForCursor(query);
        while (cursor.moveToNext()) {
        	vector.add(rowMapper.mapRow(cursor, 1));
        }
        cursor.close();
        return vector;
    }
    
    /**
     * Query for list
     * @param <T>
     * @param query builder
     * @param rowMapper
     * @return list of object
     */
    public <T> List<T> queryForList(SQLiteDatabase db,Query query, RowMapper<T> rowMapper) {
        List<T> list = new ArrayList<T>();
        Cursor cursor = queryForCursor(db,query);
        if(cursor ==null) return list;
        while (cursor.moveToNext()) {
            list.add(rowMapper.mapRow(cursor, 1));
        }
        cursor.close();
        return list;
    }
    
    /**
     * Query for cursor 
     * @param query builder
     * @return a cursor
     */
    public Cursor queryForCursor(SQLiteDatabase db,Query query) {
    	if(db==null) return null;
        query.setDb(db);
        return query.select();
    }
    
}